home *** CD-ROM | disk | FTP | other *** search
/ CD Actual Thematic 7: Programming / CDAT7.iso / Share / Codigo / hh / rsource.exe / Heretic Source / I_CYBER.C < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-14  |  6.1 KB  |  260 lines

  1. // I_cyber.c
  2.  
  3. #include <dos.h>
  4. #include <stdlib.h>
  5.  
  6.  
  7. /*
  8. ====================================================
  9.  
  10. Doom control structure
  11.  
  12. The keybaord and joystick will add to the values set by the cyberman,
  13. to a maximum of 0x19000 for forwardmove and sidemove.  Angleturn is
  14. not bounded at all.
  15.  
  16. parm                    normal          fast
  17. -----           ------          ----
  18. forwardmove             0xc800          0x19000
  19. sidemove                0xc000          0x14000
  20. angleturn               0x2800000       0x5000000
  21.  
  22. The keyboard and joystick have a 1/3 second slow turn of 0x1400000 under
  23. normal speed to help aiming.
  24.  
  25.  
  26.  
  27. ====================================================
  28. */
  29.  
  30. typedef struct
  31. {
  32.     char            forwardmove;            // *2048 for move
  33.     char            sidemove;                       // *2048 for move
  34.     short           angleturn;                      // <<16 for angle delta
  35.     short           consistancy;            // checks for net game
  36.     unsigned char            chatchar;
  37.     unsigned char           buttons;
  38. } ticcmd_t;
  39.  
  40. #define BT_ATTACK               1
  41. #define BT_USE                  2
  42. #define BT_CHANGE               4                       // if true, the next 3 bits hold weapon num
  43. #define BT_WEAPONMASK   (8+16+32)
  44. #define BT_WEAPONSHIFT  3
  45.  
  46.  
  47.  
  48. //==================================================
  49. //
  50. // CyberMan detection and usage info
  51. //
  52. //==================================================
  53. #define DPMI_INT        0x31
  54. #define MOUSE_INT       0x33
  55.  
  56. #define DOSMEMSIZE      64      // enough for any SWIFT structure
  57.  
  58. typedef struct {
  59.    short        x;
  60.    short        y;
  61.    short        z;
  62.    short        pitch;
  63.    short        roll;
  64.    short        yaw;
  65.    short        buttons;
  66. } SWIFT_3DStatus;
  67.  
  68. // DPMI real mode interrupt structure
  69. static struct rminfo {
  70.     long EDI;
  71.     long ESI;
  72.     long EBP;
  73.     long reserved_by_system;
  74.     long EBX;
  75.     long EDX;
  76.     long ECX;
  77.     long EAX;
  78.     short flags;
  79.     short ES,DS,FS,GS,IP,CS,SP,SS;
  80. } RMI;
  81.  
  82. typedef struct {
  83.    unsigned char        deviceType;
  84.    unsigned char        majorVersion;
  85.    unsigned char        minorVersion;
  86.    unsigned char        absRelFlags;
  87.    unsigned char        centeringFlags;
  88.    unsigned char        reserved[5];
  89. } StaticDeviceData;
  90.  
  91. // values for deviceType:
  92. #define DEVTYPE_CYBERMAN        1
  93.  
  94. short                   selector;
  95. unsigned short  segment;                // segment of DOS memory block
  96. SWIFT_3DStatus  *cyberstat;
  97. int                             isCyberPresent;         // is CyberMan present?
  98.  
  99.  
  100. static  union REGS regs;
  101. static  struct SREGS sregs;
  102.  
  103.  
  104. extern  int mousepresent;
  105.  
  106. //===========================================================
  107. //
  108. // I_StartupCyberMan
  109. //
  110. // If a cyberman is present, init it and set isCyberPresent to 1
  111. //===========================================================
  112. void I_StartupCyberMan(void)
  113. {
  114.    StaticDeviceData *pbuf;
  115.    int success = 0;
  116.  
  117.    isCyberPresent = 0;
  118.  
  119.    cyberstat = (SWIFT_3DStatus *)I_AllocLow (DOSMEMSIZE);
  120.    segment = (int)cyberstat>>4;
  121.  
  122.    pbuf = (StaticDeviceData *)cyberstat;
  123.    memset(pbuf, 0, sizeof (StaticDeviceData));
  124.  
  125.    // Use DPMI call 300h to issue mouse interrupt
  126.    memset(&RMI, 0, sizeof(RMI));
  127.    RMI.EAX = 0x53C1;            // SWIFT: Get Static Device Data
  128.    RMI.ES = segment;
  129.    RMI.EDX = 0;
  130.    memset(&sregs, 0, sizeof (sregs));
  131.    regs.w.ax = 0x0300;          // DPMI: simulate interrupt
  132.    regs.w.bx = MOUSE_INT;
  133.    regs.w.cx = 0;
  134.    regs.x.edi = FP_OFF(&RMI);
  135.    sregs.es = FP_SEG(&RMI);
  136.    int386x( DPMI_INT, ®s, ®s, &sregs );
  137.  
  138.    if ((short)RMI.EAX != 1)
  139.    {
  140.       // SWIFT functions not present
  141.       tprintf("CyberMan: Wrong mouse driver - no SWIFT support (AX=%04x).\n",
  142.              (unsigned)(short)RMI.EAX);
  143.    }
  144.    else
  145.    if (pbuf->deviceType != DEVTYPE_CYBERMAN)
  146.    {
  147.       // no SWIFT device, or not CyberMan
  148.       if (pbuf->deviceType == 0)
  149.       {
  150.          tprintf("CyberMan: no SWIFT device connected.\n");
  151.       }
  152.       else
  153.       {
  154.          tprintf("CyberMan: SWIFT device is not a CyberMan! (type=%d)\n",
  155.                 pbuf->deviceType);
  156.       }
  157.    }
  158.    else
  159.    {
  160.       tprintf("CyberMan: CyberMan %d.%02d connected.\n",
  161.              pbuf->majorVersion, pbuf->minorVersion);
  162.       isCyberPresent = 1;
  163.       mousepresent = 0;
  164.    }
  165. }
  166.  
  167.  
  168.  
  169. /*
  170. ===============
  171. =
  172. = I_ReadCyberCmds
  173. =
  174. ===============
  175. */
  176.  
  177.  
  178. int             oldpos;
  179.  
  180. void I_ReadCyberCmd (ticcmd_t *cmd)
  181. {
  182.     int             delta;
  183.  
  184.     // Use DPMI call 300h to issue mouse interrupt
  185.     memset(&RMI, 0, sizeof(RMI));
  186.     RMI.EAX = 0x5301;            // SWIFT: Get Position and Buttons
  187.     RMI.ES = segment;
  188.     RMI.EDX = 0;
  189.     memset(&sregs, 0, sizeof (sregs));
  190.     regs.w.ax = 0x0300;          // DPMI: simulate interrupt
  191.     regs.w.bx = MOUSE_INT;
  192.     regs.w.cx = 0;
  193.     regs.x.edi = FP_OFF(&RMI);
  194.     sregs.es = FP_SEG(&RMI);
  195.     int386x( DPMI_INT, ®s, ®s, &sregs );
  196.  
  197.     if (cyberstat->y < -7900)
  198.         cmd->forwardmove = 0xc800/2048;
  199.     else if (cyberstat->y > 7900)
  200.         cmd->forwardmove = -0xc800/2048;
  201.  
  202.     if (cyberstat->buttons & 4)
  203.         cmd->buttons |= BT_ATTACK;
  204.     if (cyberstat->buttons & 2)
  205.         cmd->buttons |= BT_USE;
  206.  
  207.     delta = cyberstat->x - oldpos;
  208.     oldpos = cyberstat->x;
  209.  
  210.     if (cyberstat->buttons & 1)
  211.     {       // strafe
  212.         if (cyberstat->x < -7900)
  213.             cmd->sidemove = -0xc800/2048;
  214.         else if (cyberstat->x > 7900)
  215.             cmd->sidemove = 0xc800/2048;
  216.         else
  217.             cmd->sidemove = delta*40/2048;
  218.     }
  219.     else
  220.     {
  221.         if (cyberstat->x < -7900)
  222.             cmd->angleturn = 0x280;
  223.         else if (cyberstat->x > 7900)
  224.             cmd->angleturn = -0x280;
  225.         else
  226.             cmd->angleturn = -delta*0xa/16;
  227.  
  228.     }
  229.  
  230. }
  231.  
  232.  
  233. void I_Tactile (int on, int off, int total)
  234. {
  235.     if (!isCyberPresent)
  236.         return;
  237.  
  238.     on /= 5;
  239.     off /= 5;
  240.     total /= 40;
  241.     if (on > 255)
  242.         on = 255;
  243.     if (off > 255)
  244.         off = 255;
  245.     if (total > 255)
  246.         total = 255;
  247.  
  248.     memset(&RMI, 0, sizeof(RMI));
  249.     RMI.EAX = 0x5330;            // SWIFT: Get Position and Buttons
  250.     RMI.EBX = on*256+off;
  251.     RMI.ECX = total;
  252.     memset(&sregs, 0, sizeof (sregs));
  253.     regs.w.ax = 0x0300;          // DPMI: simulate interrupt
  254.     regs.w.bx = MOUSE_INT;
  255.     regs.w.cx = 0;
  256.     regs.x.edi = FP_OFF(&RMI);
  257.     sregs.es = FP_SEG(&RMI);
  258.     int386x( DPMI_INT, ®s, ®s, &sregs );
  259. }
  260.